package com.ebai.product.management.service.system;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.ebai.product.management.base.cache.service.MessageCacheImpl;
import com.ebai.product.management.base.utils.SysCode;
import com.ebai.product.management.framework.utils.TreeUtils;
import com.ebai.product.management.model.entity.Auth;
import com.ebai.product.management.model.entity.User;
import com.ebai.product.management.repository.system.AuthRepository;

@Service
public class AuthService {

    @Autowired
    private AuthRepository authRepository;
    
    public List<Auth> selectAuthsByUser(User user) {
    	List<Auth> auths = new ArrayList<Auth>();
    	//管理员显示所有菜单信息
    	if (StringUtils.equals(user.getLoginName(), SysCode.DEFAULT_USER.DEFAULT_SA)) {
    		auths = authRepository.findAuthsAllMenu();
    	}
    	else {
    		List<Object> authObj = authRepository.selectAuthsByUserId(user.getPid());
    		Auth auth = null;
    		for (Object object : authObj) {
    			Object[] rowArray = (Object[]) object;
    			auth = new Auth();
    			auth.setPid((String) rowArray[0]);
    			auth.setParentAuth((String) rowArray[1]);
    			auth.setDisplayName((String) rowArray[2]);
    			auth.setDirectUrl((String) rowArray[3]);
    			auth.setAuthPerms((String) rowArray[4]);
    			auth.setAuthType((String) rowArray[5]);
    			
    			auths.add(auth);
			}
    	}
    	
		return TreeUtils.getChildPerms(auths, "0");
    }

    /**
     * 依据条件查询分页数据
     * @param page
     * @param size
     * @param authQuery
     * @return
     */
    public Page<Auth> queryPage(Integer page, Integer size, final Auth authQuery) {
        Pageable pageable = PageRequest.of(page-1, size, Sort.Direction.ASC, "sortOrder");
        Page<Auth> rolePage = this.authRepository.findAll(new Specification<Auth>(){
            public Predicate toPredicate(Root<Auth> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                // 过滤已经删除条件
                list.add(criteriaBuilder.notEqual(root.get("isDelete").as(String.class), SysCode.DICT_TYSF.YES));

                // 过滤显示名称条件
                if ( StringUtils.isNotBlank(authQuery.getDisplayName()) ){
                    list.add(criteriaBuilder.like(root.get("displayName").as(String.class), "%"+ authQuery.getDisplayName() +"%"));
                }
                // 过滤权限类型条件
                if ( StringUtils.isNotBlank(authQuery.getAuthType()) ){
                    list.add(criteriaBuilder.equal(root.get("authType").as(String.class), authQuery.getAuthType()));
                }
                // 过滤创建时间条件
                if ( StringUtils.isNotBlank(authQuery.getCreateTimeBetween()) ){
                    String[] createTime = authQuery.getCreateTimeBetween().split(" ~ ");
                    list.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[0] + " 00:00:00")));
                    list.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(Timestamp.class), Timestamp.valueOf(createTime[1] + " 23:59:59")));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);

        return rolePage;
    }

    /**
     * 依据条件查询对象是否存在
     * @param displayName
     * @return
     */
    public Map<String, Object> checkExist(String displayName) {
        Map<String, Object> result = new HashMap<String, Object>();

        Auth auth = this.queryByDisplayName(displayName);
        if (null != auth) {
            result.put("success", true);
            result.put("msg", MessageCacheImpl.getMsg("Global.Operate.Message.Repeat"));
        }
        else {
            result.put("success", false);
        }

        return result;
    }

    /**
     * 依据条件获取数据对象
     * @param displayName
     * @return
     */
    public Auth queryByDisplayName(String displayName) {
        return this.authRepository.findRoleByDisplayName(displayName);
    }

    /**
     * 保存或更新表单数据
     * @param entity
     * @return
     */
    public Map<String, Object> saveData(Auth entity) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isBlank(entity.getPid())) {
                entity.setIsDelete(SysCode.DICT_TYSF.NO);
                this.authRepository.save(entity);
            }
            else {
                Auth auth = this.authRepository.findByPid(entity.getPid());
                auth.setParentAuthText(entity.getParentAuthText());
                auth.setParentAuth(entity.getParentAuth());
                auth.setDisplayName(entity.getDisplayName());
                auth.setAuthDescribe(entity.getAuthDescribe());
                auth.setAuthPerms(entity.getAuthPerms());
                auth.setDirectUrl(entity.getDirectUrl());
                auth.setSortOrder(entity.getSortOrder());
                if (StringUtils.isNotBlank(entity.getIsDelete())) {
                    auth.setIsDelete(entity.getIsDelete());
                }
                auth.setLastUpdateTime(null);
                this.authRepository.save(auth);
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.SaveData.Message.Failure") + e.getMessage());
        }

        return result;
    }

    /**
     * 依据主键执行逻辑删除
     * @param ids
     * @return
     */
    public Map<String, Object> dropData(String ids) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("success", Boolean.FALSE);

        try {
            if (StringUtils.isNotBlank(ids)) {
                for (String pid : ids.split(",")) {
                    Auth entity = this.authRepository.findByPid(pid);
                    entity.setIsDelete(SysCode.DICT_TYSF.YES);
                    this.authRepository.save(entity);
                }
            }

            result.put("success", Boolean.TRUE);
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Success"));
        }
        catch (Exception e) {
            e.printStackTrace();
            result.put("msg", MessageCacheImpl.getMsg("Global.DeleteData.Message.Failure") + e.getMessage());
        }

        return result;
    }
    
    /**
     * 根据用户ID查询菜单按钮等权限列表
     * 
     * @param userId 用户ID
     * @return 权限列表
     */
    public Set<String> selectPermsByUserId(String userPid) {
        List<Object> perms = authRepository.selectPermsByUserId(userPid);
        Set<String> permsSet = new HashSet<>();
        for (Object perm : perms)  {
            if (null != perm) {
                permsSet.add((String) perm);
            }
        }
        return permsSet;
    }
    
}
